package com.manong.utils;

import com.manong.entity.Permission;
import com.manong.vo.RouterVo;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 生成菜单树
 * @author 李茂鑫
 * @Date 2025/1/8 11:59
 * @Descripition
 */

public class MenuTree {
    /**
     * 生成路由
     * @param menuList 菜单列表
     * @param pid  父级菜单
     * @return
     * makeRouter方法：从给定的菜单列表中，根据父菜单 ID (pid) 构建一个路由树
     */
    public static List<RouterVo>makeRouter(List<Permission>menuList,long pid){
        List<RouterVo>routerVoList=new ArrayList<RouterVo>();
        //创建集合保存路由列表
        Optional.ofNullable(menuList).orElse(new ArrayList<Permission>())
                //Optional 主要用于解决空指针异常，并且提供了许多方法来处理可能为空的对象，避免直接操作 null 值
                //确保如果 menuList 为 null，就返回一个空的 ArrayList<Permission>，避免 NullPointerException。
                .stream().filter(item -> item != null && item.getParentId() == pid).forEach(item -> {
                    // 使用 stream() 流操作，过滤出 parentId 等于 pid 的菜单项
                    RouterVo routerVo = new RouterVo();
                    //创建路由对象
                    routerVo.setName(item.getName());
                    //设置路由名称
                    routerVo.setPath(item.getPath());
                    //设置路由路径
                    if (item.getParentId() == 0L) {
                        //判断该菜单项是否是顶级菜单
                        routerVo.setComponent("Layout");
                        //设置一级菜单的组件为 Layout（默认路由布局）
                        //一级菜单组件
                        routerVo.setAlwaysShow(true);
                        //显示路由
                    } else {
                        routerVo.setComponent(item.getUrl());
                        //设置菜单项的组件为它的URL。
                        //菜单始终不显示，折叠路由
                    }
                    routerVo.setMeta(routerVo.new Meta(item.getLabel(), item.getIcon(), item.getCode().split(",")));
                    //设置元信息（meta）
                    //item.getLabel()：获取菜单项的标签
                    // item.getIcon()：获取菜单项的图标
                    // item.getCode().split(",")：获取菜单项的代码，并将其按逗号分割成字符串数组。
                    List<RouterVo> children = makeRouter(menuList, item.getId());
                    //递归构建子路由
                    routerVo.setChildren(children);
                    routerVoList.add(routerVo);
                });
        return routerVoList;

    }

    /**
     * makeMenuTree 方法：从给定的菜单列表中，递归构建一个菜单树
     * @param menuList
     * @param pid
     * @return
     */
    public static List<Permission>makeMenuTree(List<Permission>menuList,long pid){
        List<Permission>permissionList=new ArrayList<Permission>();
        //创建集合保存路由列表
        Optional.ofNullable(menuList).orElse(new ArrayList<Permission>()).stream().filter(item -> item != null && Objects.equals(item.getParentId(), pid))
                //果 menuList 为 null，则使用一个新的空 ArrayList<Permission> 替代。然后，调用 stream() 方法将列表转换为流
                //filter 方法过滤出所有非空且父级ID等于方法参数 pid 的菜单项。
                .forEach(item -> {
                    //创建菜单权限对象
                    Permission permission = new Permission();
                    //复制属性
                    BeanUtils.copyProperties(item, permission);
                    //获取每一个item的下级菜单，递归生成菜单树
                    List<Permission> children = makeMenuTree(menuList, item.getId());
                    //设置子菜单
                    permission.setChildren(children);
                    //将菜单添加到菜单列表中
                    permissionList.add(permission);
                });//也可以使用递归
        return permissionList;
    }

}
